#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include "../include/hash.h"
#include "../include/llist.h"
#include "../include/narytree.h"
#include "../include/string_tok.h"


/* initialize all the l_node *  in h_bucket to NULL */
void hash_initialize(l_node **hash)
{
    int i;
    for(i=0;i<62;i++)
    {
        hash[i]=NULL;
    }
}

int hash_insert(l_node *h_bucket[], fd* data)
{
    int bucketNo=hash_value(data->file_name[0]);
    h_node *new_node;
    new_node=(h_node *)malloc(sizeof(h_node));
    new_node->fd_id=data->fd_id;
    new_node->file_desc=data;
    strcpy(new_node->file_name,data->file_name);
    strcpy(new_node->path,data->path);
    if (bucketNo==-1) return 1;
    h_bucket[bucketNo]=list_insert_sortorder(h_bucket[bucketNo],new_node,data->file_name);
    return 0;
}

int hash_delete(l_node *h_bucket[],char *path, char *file_name)
/* Return 0 on success and non-zero on failure */
{
	int count;
    h_node *data=(h_node *)malloc(sizeof(h_node));
    int bucketNo=hash_value(file_name[0]);
    h_node **datam;
    if (bucketNo==-1) return -1;
    count=list_get_data_list(h_bucket[bucketNo] , file_name,&datam);
    if(count==0) return -1;
    strcpy(data->file_name,file_name);
    strcpy(data->path,path);
    h_bucket[bucketNo]=list_delete_node(h_bucket[bucketNo],data);
    return 0;
}

int hash_search(l_node *h_bucket[], char *file_name, fd **list[])
/* list of fds as search result in *list */
{
    int bucketNo=hash_value(file_name[0]);
    h_node **data;
    int i;
    int count=list_get_data_list(h_bucket[bucketNo] , file_name,&data);
    *list=(fd **)malloc(count * sizeof(fd *));
    for(i=0;i<count;i++)
        (*list)[i]=data[i]->file_desc;
    return count;
    
}

static int hash_value(char key)
/*Gets the hash value of the key in argument */
{
    if(key >= 'A' && key <= 'Z')
        return key - 'A' +10;
    if(key >= 'a' && key <= 'z')
        return key - 'a' + 36;
    if(key >= '0' && key <= '9')
        return key - '0';
    return -1;
}

void hash_print(l_node *h_bucket[])
{
    int i;
    l_node *cur_node;
    for(i=0;i<62;i++)
    {
        cur_node=h_bucket[i];
        if(cur_node!=NULL) printf("Hash %d\n",i);
        while(cur_node!=NULL)
        {
             printf("\t%s/%s\n",((h_node *)cur_node->data)->path,((h_node *)cur_node->data)->file_name);
             cur_node=cur_node->next;
        }
    }
}

int hash_find(l_node *h_bucket[], char *filename, FILE *fp1, int len)
{
	t_node *root = NULL;	
	int i,count=0,bucketNo,cnt=0;
	l_node *cur_node;
	h_node **data;
	fprintf(fp1,"FILE: ");
	for(i=0;i<62;i++)
	{
		cur_node=h_bucket[i];
		while(cur_node!=NULL)
		{
			if (strncmp((((h_node *)cur_node->data)->file_name),filename,len)==0)
			{
				fprintf(fp1,"\t%s/%s\t",((h_node *)cur_node->data)->path,((h_node *)cur_node->data)->file_name);
				count=hash_search(h_bucket,((h_node *)cur_node->data)->file_name,data);
				cnt=cnt+1;
			}
			cur_node=cur_node->next;
			
		}
	}
	fprintf(fp1,"\t%d",cnt);
	return cnt;
}
